import sys
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout, 
                              QSlider, QPushButton, QListWidget, QComboBox)
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
from PySide6.QtCore import Qt, QUrl, QTimer


class MusicPlayer(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("音乐播放器")
        self.resize(400, 300)
        
        # 播放列表（歌曲URL列表）
        self.playlist = []
        self.current_index = 0
        self.loop_mode = 0  # 0:列表循环 1:单曲循环
        
        self.init_ui()
        self.init_player()
        
    def init_ui(self):
        # 主布局
        main_layout = QVBoxLayout()
        
        # 播放列表显示
        self.list_widget = QListWidget()
        self.list_widget.itemDoubleClicked.connect(self.play_selected)
        main_layout.addWidget(self.list_widget)
        
        # 播放控制区域
        control_layout = QVBoxLayout()
        
        # 进度条
        self.slider = QSlider(Qt.Horizontal)
        self.slider.sliderMoved.connect(self.set_position)
        control_layout.addWidget(self.slider)
        
        # 按钮和循环模式
        button_layout = QHBoxLayout()
        
        self.play_btn = QPushButton("播放")
        self.play_btn.clicked.connect(self.toggle_play)
        button_layout.addWidget(self.play_btn)
        
        self.prev_btn = QPushButton("上一首")
        self.prev_btn.clicked.connect(self.prev_song)
        button_layout.addWidget(self.prev_btn)
        
        self.next_btn = QPushButton("下一首")
        self.next_btn.clicked.connect(self.next_song)
        button_layout.addWidget(self.next_btn)
        
        # 循环模式选择
        self.loop_combo = QComboBox()
        self.loop_combo.addItems(["列表循环", "单曲循环"])
        self.loop_combo.currentIndexChanged.connect(self.set_loop_mode)
        button_layout.addWidget(self.loop_combo)
        
        control_layout.addLayout(button_layout)
        main_layout.addLayout(control_layout)
        
        self.setLayout(main_layout)
    
    def init_player(self):
        # 初始化播放器
        self.player = QMediaPlayer()
        self.audio_output = QAudioOutput()
        self.player.setAudioOutput(self.audio_output)
        
        # 连接信号
        self.player.positionChanged.connect(self.update_position)
        self.player.durationChanged.connect(self.update_duration)
        self.player.playbackStateChanged.connect(self.update_button_text)
        self.player.mediaStatusChanged.connect(self.handle_media_status)
        
        # 定时器用于检测歌曲结束（更可靠的方式）
        self.end_timer = QTimer()
        self.end_timer.setInterval(500)
        self.end_timer.timeout.connect(self.check_song_end)
    
    def add_songs(self, file_paths):
        """添加歌曲到播放列表"""
        for path in file_paths:
            self.playlist.append(QUrl.fromLocalFile(path))
            self.list_widget.addItem(path.split("/")[-1])  # 显示文件名
    
    def play_song(self, index):
        """播放指定索引的歌曲"""
        if 0 <= index < len(self.playlist):
            self.current_index = index
            self.player.setSource(self.playlist[index])
            self.player.play()
            self.list_widget.setCurrentRow(index)
            self.end_timer.start()
    
    def play_selected(self):
        """播放用户选择的歌曲"""
        index = self.list_widget.currentRow()
        if index != -1:
            self.play_song(index)
    
    def toggle_play(self):
        """播放/暂停切换"""
        if self.player.playbackState() == QMediaPlayer.PlayingState:
            self.player.pause()
        else:
            if self.player.source().isEmpty():  # 如果没有设置歌曲，播放第一首
                if self.playlist:
                    self.play_song(0)
            else:
                self.player.play()
    
    def prev_song(self):
        """上一首"""
        if self.loop_mode == 1 and self.player.position() > 3000:  # 单曲循环模式下，超过3秒重新播放
            self.player.setPosition(0)
        else:
            new_index = (self.current_index - 1) % len(self.playlist)
            self.play_song(new_index)
    
    def next_song(self):
        """下一首"""
        new_index = (self.current_index + 1) % len(self.playlist)
        self.play_song(new_index)
    
    def set_loop_mode(self, mode):
        """设置循环模式"""
        self.loop_mode = mode
    
    def update_position(self, position):
        """更新进度条位置"""
        if not self.slider.isSliderDown():
            self.slider.setValue(position)
    
    def update_duration(self, duration):
        """更新歌曲总时长和进度条范围"""
        self.slider.setRange(0, duration)
    
    def set_position(self, position):
        """用户拖动进度条时设置播放位置"""
        self.player.setPosition(position)
    
    def update_button_text(self, state):
        """更新播放按钮文本"""
        if state == QMediaPlayer.PlayingState:
            self.play_btn.setText("暂停")
        else:
            self.play_btn.setText("播放")
    
    def check_song_end(self):
        """检查歌曲是否播放结束"""
        if (self.player.position() >= self.player.duration() - 100 and 
            self.player.duration() > 0):
            self.handle_song_end()
    
    def handle_song_end(self):
        """处理歌曲结束事件"""
        self.end_timer.stop()
        
        if self.loop_mode == 1:  # 单曲循环
            self.player.setPosition(0)
            self.player.play()
            self.end_timer.start()
        else:  # 列表循环
            self.next_song()
    
    def handle_media_status(self, status):
        """处理媒体状态变化"""
        if status == QMediaPlayer.EndOfMedia:
            self.handle_song_end()
        elif status == QMediaPlayer.LoadedMedia:
            self.end_timer.start()
        elif status == QMediaPlayer.InvalidMedia:
            print("无法加载媒体文件")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    player = MusicPlayer()
    player.show()
    
    # 添加歌曲（替换为你的实际文件路径）
    songs = [
        "source/稻香.mp3",
        "source/蒲公英的约定.mp3",
    ]
    player.add_songs(songs)
    
    sys.exit(app.exec())